#ifndef __SPJ_VERIFY_EVENT_HPP__
#define __SPJ_VERIFY_EVENT_HPP__

#include "base_event.hpp"

namespace run_code_event_space {

struct spj_verify_event : base_event<spj_verify_event>  {
    template <class U>
    ProcessStatus execute_impl(run_code_context_t<U>& context, const string& inFile);
};

template <class U>
ProcessStatus spj_verify_event::execute_impl(run_code_context_t<U>& context, const string& inFile) {
    const RuncodeParams& params = context.params;
    ProcessStatus ps;
    // 将标准输入样例和用户进程输出作为特判进程的输入
    int spj_pipe[2];
    pipe(spj_pipe);
    std::ifstream in_data(inFile);
    if (!in_data.is_open()) {
        ps.result = SYS_ERROR;
        ps.error = "spjType verify->open file error:" + inFile;
        return ps;
    }
    int res;
    res = streamToFileno(in_data, spj_pipe[1]);
    if (res < 0) {
        ps.result = PIPE_ERROR;
        ps.error = "stream to fileno error";
        return ps;
    }
    // 如果in_data非空则保证中间隔一个换行
    if (res > 0) {
        in_data.clear();
        in_data.seekg(-1, in_data.end);
        if (in_data.get() != '\n') {
            Log::instance().getOutput() << "need new line" << endl;
            write(spj_pipe[1], "\n", 1);
        }
    }
    res = streamToFileno(std::stringstream(context.get_latest_status().output), spj_pipe[1]);
    if (res < 0) {
        ps.result = PIPE_ERROR;
        ps.error = "stream to fileno error";
        return ps;
    }
    // 最后关闭读 
    defer(
        close(spj_pipe[0]);
        close(spj_pipe[1]);
    );
    // 将eps作为命令行参数传入
    string command = context.judge_type.spjCodeInfo.runStr + " " + params.eps;
    ps = commandExecuteResult(command, params.timeLimit, 0, 0, ProcessSTDNO(spj_pipe[0], -1, -1));
    return ps;
}

}

#endif /* __SPJ_VERIFY_EVENT_HPP__ */
